package com.tuniu.agents.tools.flights.utils;

import com.tuniu.agents.tools.flights.FlightProperties;
import com.tuniu.agents.util.HttpManager;


import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Utility class for querying city codes and three-letter codes.
 */
public class CityCodeUtils {

    private static String URL;

    private static String key;

    public CityCodeUtils(FlightProperties flightProperties) {
        this.URL = flightProperties.getCityCodeUrl();
        this.key = flightProperties.getCityCodeKey();

    }

    private static final Map<String, Ext> CITY_MAP = new ConcurrentHashMap<>();

    /**
     * Query city information
     *
     * @param httpManager HTTP manager
     * @param cityName Name of the city to query
     * @return City code information
     */
    public static Ext getCityCode(HttpManager httpManager, String cityName) {
        if (CITY_MAP.containsKey(cityName)) {
            return CITY_MAP.get(cityName);
        }
        RequestParam param = new RequestParam();
        param.setName(cityName);
        Object res = httpManager.getWithBase64Response(URL, param, ResponseParam.class, true, Map.of("accessKey", key));
        if (res != null) {
            ResponseParam p = (ResponseParam) res;
            if (p.getData() != null) {
                List<CityRes> result = p.getData().getResult();
                if (result != null && result.size() > 0) {
                    Ext ext = result.get(0).getExt_fields();
                    ext.setCode(result.get(0).getId());
                    CITY_MAP.put(cityName, ext);
                    return ext;
                }
            }
        }
        return new Ext();
    }

    public static class RequestParam {
        private String type_id;
        private String page;
        private String limit;
        private String fields;

        /**
         * City name
         */
        private String name;

        public RequestParam() {
            this.type_id = "10";
            this.page = "1";
            this.limit = "1";
            this.fields = "id,name,ext_fields";
        }

        public String getType_id() {
            return type_id;
        }

        public void setType_id(String type_id) {
            this.type_id = type_id;
        }

        public String getPage() {
            return page;
        }

        public void setPage(String page) {
            this.page = page;
        }

        public String getLimit() {
            return limit;
        }

        public void setLimit(String limit) {
            this.limit = limit;
        }

        public String getFields() {
            return fields;
        }

        public void setFields(String fields) {
            this.fields = fields;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static class Ext {
        private String py; // Pinyin
        private String jp; // Abbreviation
        private String iata_code; // IATA code
        private String two_iata_code; // Two-letter IATA code
        private String alias; // Alias
        private String order_field; // Order field
        private String travel_num; // Travel number
        private String update_time; // Update time
        private String add_time; // Add time

        private String code; // City code

        public String getPy() {
            return py;
        }

        public void setPy(String py) {
            this.py = py;
        }

        public String getJp() {
            return jp;
        }

        public void setJp(String jp) {
            this.jp = jp;
        }

        public String getIata_code() {
            return iata_code;
        }

        public void setIata_code(String iata_code) {
            this.iata_code = iata_code;
        }

        public String getTwo_iata_code() {
            return two_iata_code;
        }

        public void setTwo_iata_code(String two_iata_code) {
            this.two_iata_code = two_iata_code;
        }

        public String getAlias() {
            return alias;
        }

        public void setAlias(String alias) {
            this.alias = alias;
        }

        public String getOrder_field() {
            return order_field;
        }

        public void setOrder_field(String order_field) {
            this.order_field = order_field;
        }

        public String getTravel_num() {
            return travel_num;
        }

        public void setTravel_num(String travel_num) {
            this.travel_num = travel_num;
        }

        public String getUpdate_time() {
            return update_time;
        }

        public void setUpdate_time(String update_time) {
            this.update_time = update_time;
        }

        public String getAdd_time() {
            return add_time;
        }

        public void setAdd_time(String add_time) {
            this.add_time = add_time;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }
    }

    public static class CityRes {
        private String id; // City ID
        private String name; // City name
        private String type_id; // Type ID
        private Ext ext_fields; // Extended fields

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getType_id() {
            return type_id;
        }

        public void setType_id(String type_id) {
            this.type_id = type_id;
        }

        public Ext getExt_fields() {
            return ext_fields;
        }

        public void setExt_fields(Ext ext_fields) {
            this.ext_fields = ext_fields;
        }
    }

    public static class CityData {
        private String pageCount;
        private List<CityRes> result;

        public String getPageCount() {
            return pageCount;
        }

        public void setPageCount(String pageCount) {
            this.pageCount = pageCount;
        }

        public List<CityRes> getResult() {
            return result;
        }

        public void setResult(List<CityRes> result) {
            this.result = result;
        }
    }

    public static class ResponseParam {
        private Boolean success;  // Success indicator: "Query successful!" for success, "Query failed!" for failure
        private String msg;
        private CityData data;  // Returned city data

        public Boolean getSuccess() {
            return success;
        }

        public void setSuccess(Boolean success) {
            this.success = success;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public CityData getData() {
            return data;
        }

        public void setData(CityData data) {
            this.data = data;
        }
    }
}